<?php
namespace app\wechat\controller;

use think\Request;

import('Tools/Aes', VENDOR_PATH);
import('Tools/Rsa', VENDOR_PATH);

//include_once VENDOR_PATH.'Tools\Aes.php';
//include_once VENDOR_PATH.'Tools\Rsa.php';

/**
 * 接口服务
 * 学通宝·蚂蚁·商户 聚合支付
 *
 */
class Businesspay extends Common
{
    //定义全局常量
    protected $config;
    //dev开发环境
    protected $env = APP_ENV;

    private $strKey;
    //商户在学通宝开放平台查看应用ID
    private $appId;
    //后台通知地址
    private $notifyUrl;
    private $callback;

    //服务类型
    private $service = [
        1=>'services.type.wechatnative',	//微信扫码
        2=>'services.type.wechatjsapi',		//微信公众号
        3=>'services.type.wechatapp',		//微信APP
        4=>'services.type.wechath5',		//微信H5
        5=>'services.type.alipay',			//支付宝扫码
        6=>'services.type.alipaywap',		//支付宝手机网站
        7=>'services.type.alipaypc',		//支付宝电脑网站(暂未开通)
        8=>'services.type.alipayapp',		//支付宝APP
    ];

    public function __construct($appId='',$key='',$notify='',$callback='') {
        parent::__construct();
        $this->config = config('xtbpay.' . $this->env);

        $this->appId = $appId;
        $this->strKey = $key;
        $this->notifyUrl = $notify;
        $this->callback = $callback;

    }


    /*
     * @pay统一下单支付
     * @DateTime 2018-06-05
     * @param      $sn      [随机订单号]
     * @param      $amount  [交易金额]
     * @param      $body    [商品名称]
     * @param      $service [服务类型]
     * @param      $openId  [微信公众号的openId]
     */
    function orderPay($sn='',$amount='0.01',$body='',$service='',$openId='',$wxappid){

        //组装数据
        $payOptions = array(
            'services'          => $this->service[$service],//服务类型
            'version'           => 'v3.0.2',//版本号
            'merchantOrderNo'   => $sn,//订单编号
            'subject'           => $body,//商品名称
            'body'              => $body,//商品详情
            'amount'            => strval($amount),//交易金额
            'tranDateTime'      => date('YmdHis'),//发起交易时间
            'notifyUrl'         => $this->notifyUrl,//后台通知地址
            'frontJumpUrl'      => $this->callback,//前台跳转地址
            'clientIp'          => getenv("REMOTE_ADDR"),//请求IP地址
            'openId'            => $openId,//微信公众号的openId
            'subWechatId'       => $wxappid,
        );
//        print_r($payOptions);exit;
        return $this->commonAction($this->config['pay_url'],$payOptions);
    }

    /*
     * 学通宝订单查询接口
     */
    public function checkOrder($sn){
        $payOptions = array(
            'merchantOrderNo'=>  $sn,
        );

        return $this->commonAction($this->config['check_url'],$payOptions);
    }


    /**
     * 通用解密方法
     *
    */
    public function decryptionAction($data=array()){

        $aes = new \Aes();
        $rsa = new \Rsa();

        $payOptionsArr = json_decode($data);

        //解密AES密钥(使用商户私钥解密得到AesKey)
        $aesKey = $rsa->privateDecrypt($payOptionsArr->encryptKey,$rsa->privateKey);
        //使用AES密钥解密返回数据(使用解密encryptKey得到的AesKey解密该数据)
        $encData = json_decode($aes->AESDecryptResponse($aesKey,$payOptionsArr->encryptData));
        //请求报文签名，签名以及平台返回信息解密传输密钥用（学通宝公钥验签）
//        $signData = $rsa->getSign(utf8_decode($encData),$rsa->xtbPriKey);

        return $encData;
    }


    /*
     *  通用加密方法
     */
    private function commonAction($url,$payOptions){

        $aes = new \Aes();
        $rsa = new \Rsa();

        $payOptionsJson = json_encode($payOptions);

        //接口请求参数
        $connectOptions = [
            //商户在学通宝开放平台查看应用ID
            'appId'         =>$this->appId,
            //加密后的请求报文。（使用商户生成的AesKey加密）
            'encryptData'   =>$aes->AESEncryptRequest($this->strKey,$payOptionsJson),
            //加密后的AES对称密钥（使用学通宝公钥加密）
            'encryptKey'    =>$rsa->publicEncrypt($this->strKey,$rsa->xtbPriKey),
            //请求报文签名。（使用商户私钥签名）
            'signData'      =>$rsa->getSign(utf8_encode($payOptionsJson),$rsa->privateKey),
        ];
//        print_r($connectOptions);exit;
        try{
            $rear = $this->http_post_json($url, json_encode($connectOptions));
//            print_r($rear);exit;
            if(!empty($rear)){
                $data = json_decode($rear[1]);
                if($data->respCode){
                    return array('code'=>0,'msg'=>$data->respMsg);
                }else{
                    //解密AES密钥
                    $aesKey = $rsa->privateDecrypt($data->encryptKey,$rsa->privateKey);
                    //使用AES密钥解密返回数据
                    $encData = json_decode($aes->AESDecryptResponse($aesKey,$data->encryptData));

                    if(intval($encData->respCode) == 0000){
                        unset($encData->respCode);
                        unset($encData->respMsg);
                        return array(
                            'code'=>1,
                            'msg'=>$encData->respMsg,
                            'data'=>$encData
                        );
                    }
                }
                return array('code'=>0,'msg'=>$encData->respMsg);
            }
            return array('code'=>0,'msg'=>'接口请求失败');
        }catch (\Exception $e){
            return array(0,'接口访问错误');
        }
    }


    /**
     * PHP发送Json对象数据
     * @param $url 请求url
     * @param $jsonStr 发送的json字符串
     * @return array
     */
    function http_post_json($url, $jsonStr)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Content-Type: application/json; charset=utf-8',
                'Content-Length: ' . strlen($jsonStr)
            )
        );
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return array($httpCode, $response);
    }







}
